home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Ghost 1.0 / source / Ghost ƒ / Ghost code / ghost strategy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  5.5 KB  |  279 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        ghost strategy.c
  4.  
  5. Purpose:    This module handles computer player strategy -- looking
  6.             at the dictionary and figuring out the best move.
  7.             
  8.  
  9.  
  10. Ghost -=- a classic word-building challenge
  11. Copyright (C) 1993 Mark Pilgrim
  12.  
  13. This program is free software; you can redistribute it and/or modify
  14. it under the terms of the GNU General Public License as published by
  15. the Free Software Foundation; either version 2 of the License, or
  16. (at your option) any later version.
  17.  
  18. This program is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. GNU General Public License for more details.
  22.  
  23. You should have received a copy of the GNU General Public License
  24. along with this program in a file named "GNU General Public License".
  25. If not, write to the Free Software Foundation, 675 Mass Ave,
  26. Cambridge, MA 02139, USA.
  27.  
  28. \**********************************************************************/
  29.  
  30. #include "ghost globals.h"
  31. #include "ghost strategy.h"
  32. #include "ghost end.h"
  33. #include "msg graphics.h"
  34. #include "msg dialogs.h"
  35. #include "msg timing.h"
  36.  
  37. #define whichList    gTheWord[1]-'A'
  38.  
  39. long            listPtr;
  40. long            startPtr;
  41. long            oldStartPtr;
  42. Str255            thisWord;
  43.  
  44. static int        screwMe[26],screwThem[26];
  45.  
  46. void DoComputerPlayer(void)
  47. {
  48.     Boolean            nextPlayerIsHuman;
  49.     
  50.     StartTiming();
  51.     if (gTheWord[0]==0x00)
  52.         AddLetter(RandomChoice());
  53.     else if (gTheWord[0]==0x01)
  54.     {
  55.         if (gComputerIntelligence==0x03)
  56.             AddLetter(SmartChoice());
  57.         else
  58.             AddLetter(RandomChoiceButRealWord());
  59.     }
  60.     else
  61.     {
  62.         switch (gComputerIntelligence)
  63.         {
  64.             case 0x01:
  65.                 AddLetter(RandomChoiceButRealWord());
  66.                 break;
  67.             case 0x02:
  68.                 if (((Random()&0x7fff)%2)==1)
  69.                     AddLetter(RandomChoiceButRealWord());
  70.                 else
  71.                     AddLetter(SmartChoice());
  72.                 break;
  73.             case 0x03:
  74.                 GoToNextPlayer();
  75.                 nextPlayerIsHuman=(gPlayOrderIndex[gCurrentPlayer]<gNumHumanPlayers);
  76.                 GoToPreviousPlayer();
  77.                 
  78.                 if (nextPlayerIsHuman)
  79.                 {
  80.                     if (((Random()&0x7fff)%4)==1)
  81.                         AddLetter(RandomChoice());
  82.                     else
  83.                         AddLetter(SmartChoice());
  84.                 }
  85.                 else AddLetter(SmartChoice());
  86.                 break;
  87.         }
  88.     }
  89. }
  90.  
  91. char RandomChoice(void)
  92. {
  93.     return ('A'+(Random()&0x7fff)%26);
  94. }
  95.  
  96. char RandomChoiceButRealWord(void)
  97. {
  98.     char            theChar;
  99.     Boolean            atLeastOne;
  100.     int                i;
  101.     
  102.     atLeastOne=FALSE;
  103.     SearchList();
  104.     for (i=0; (i<26) && (!atLeastOne); i++)
  105.         atLeastOne|=((screwThem[i]>0) || (screwMe[i]>0));
  106.         
  107.     if (atLeastOne)
  108.     {
  109.         do
  110.         {
  111.             theChar='A'+(Random()&0x7fff)%26;
  112.         }
  113.         while ((screwThem[theChar-'A']==0) && (screwMe[theChar-'A']==0));
  114.         
  115.         return theChar;
  116.     }
  117.     else return ' ';
  118. }
  119.  
  120. char SmartChoice(void)
  121. {
  122.     int                bestMe, bestThem;
  123.     char            bestChar;
  124.     int                theIndex;
  125.     char            theChar;
  126.     char            startChar;
  127.     Boolean            goon;
  128.     
  129.     SearchList();
  130.     bestMe=9999;
  131.     bestThem=0;
  132.     bestChar=' ';
  133.     theChar=startChar='A'+((Random()&0x7fff)%26);
  134.     goon=TRUE;
  135.     
  136.     do
  137.     {
  138.         theIndex=theChar-'A';
  139.         
  140.         if ((screwMe[theIndex]>0) && (screwThem[theIndex]>0))
  141.         {
  142.             if (screwThem[theIndex]/screwMe[theIndex]>=bestThem/bestMe)
  143.             {
  144.                 bestMe=screwMe[theIndex];
  145.                 bestThem=screwThem[theIndex];
  146.                 bestChar=theChar;
  147.             }
  148.         }
  149.         else if ((screwMe[theIndex]==0) && (screwThem[theIndex]>0))
  150.         {
  151.             bestChar=theChar;
  152.             goon=FALSE;
  153.         }
  154.         else if ((screwMe[theIndex]>0) && (screwThem[theIndex]==0))
  155.         {
  156.             if ((bestThem==0) && (screwMe[theIndex]<=bestMe))
  157.             {
  158.                 bestMe=screwMe[theIndex];
  159.                 bestChar=theChar;
  160.             }
  161.         }
  162.         theChar++;
  163.         if (theChar>'Z')
  164.             theChar='A';
  165.     }
  166.     while ((theChar!=startChar) && (goon));
  167.     
  168.     return bestChar;
  169. }
  170.  
  171. void FindStartPtr(Boolean updateOldStartPtr)
  172. {
  173.     Boolean            match;
  174.     
  175.     if ((updateOldStartPtr) && (gTheWord[0]==0x01))
  176.         oldStartPtr=startPtr=gIndex[gUseFullDictionary ? kFull : kPartial][gTheWord[1]-'A'];
  177.     
  178.     listPtr=oldStartPtr;
  179.     if (gTheWord[0]>0x01)
  180.     {
  181.         do
  182.         {
  183.             GetNextWord(FALSE);
  184.             match=MatchWord();
  185.             if (!match)
  186.                 GetNextWord(TRUE);
  187.         }
  188.         while ((!match) && (listPtr<gIndex[gUseFullDictionary ? kFull : kPartial][whichList+1]));
  189.     }
  190.     else match=FALSE;
  191.  
  192.     if (updateOldStartPtr)
  193.         oldStartPtr=startPtr;
  194.  
  195.     startPtr=listPtr;
  196. }
  197.  
  198. Boolean FindOneOccurrence(void)
  199. {
  200.     Boolean        found;
  201.     
  202.     found=FALSE;
  203.     FindStartPtr(FALSE);
  204.     listPtr=startPtr;
  205.     while ((!found) && (listPtr<gIndex[gUseFullDictionary ? kFull : kPartial][whichList+1]))
  206.     {
  207.         GetNextWord(TRUE);
  208.         if (MatchWord())
  209.             found=TRUE;
  210.     }
  211.     
  212.     return found;
  213. }
  214.  
  215. void SearchList(void)
  216. {
  217.     Boolean            match;
  218.     int                i;
  219.     
  220.     FindStartPtr(FALSE);
  221.     for (i=0; i<26; i++)
  222.         screwMe[i]=screwThem[i]=0;
  223.     listPtr=startPtr;
  224.     match=TRUE;
  225.     while ((match) && (listPtr<gIndex[gUseFullDictionary ? kFull : kPartial][whichList+1]))
  226.     {
  227.         GetNextWord(TRUE);
  228.         match=MatchWord();
  229.         if (match)
  230.         {
  231.             if ((thisWord[0]-gTheWord[0]-1)%(gActualHumanPlayers+gActualComputerPlayers))
  232.                 screwThem[thisWord[gTheWord[0]+1]-'A']++;
  233.             else
  234.                 screwMe[thisWord[gTheWord[0]+1]-'A']++;
  235.         }
  236.     }
  237. }
  238.  
  239. void GetNextWord(Boolean updateListPtr)
  240. {
  241.     char            oneChar;
  242.     long            tempPtr;
  243.     
  244.     tempPtr=listPtr;
  245.     thisWord[0]=0x00;
  246.     if (listPtr<gIndex[gUseFullDictionary ? kFull : kPartial][whichList+1])
  247.     {
  248.         do
  249.         {
  250.             oneChar=*((char*)((long)(gTheDictionary[gUseFullDictionary ? kFull : kPartial])+(tempPtr++)));
  251.             if (oneChar!=0x0d)
  252.                 thisWord[++thisWord[0]]=oneChar;
  253.         }
  254.         while (oneChar!=0x0d);
  255.         if (updateListPtr)
  256.             listPtr=tempPtr;
  257.     }
  258. }
  259.  
  260. Boolean MatchWord(void)
  261. {
  262.     int                i;
  263.     Boolean            match;
  264.     
  265.     i=gTheWord[0];
  266.     if (thisWord[0]<i)
  267.         match=FALSE;
  268.     else
  269.     {
  270.         do
  271.         {
  272.             match=(gTheWord[i]==thisWord[i]);
  273.             i--;
  274.         }
  275.         while ((i>0) && (match));
  276.     }
  277.     return match;
  278. }
  279.